/**
 * 
 */
package neptune.manager.builder;

import neptune.manager.model.topology.NetworkInterface;
import neptune.manager.model.topology.Node;
import neptune.manager.model.topology.Topology;
import neptune.manager.storage.ExperimentRepositoryException;
import neptune.manager.storage.StorageReadException;
import neptune.manager.storage.TopologyDefinitionException;
import neptune.manager.utils.DebugLog;
import neptune.manager.utils.Logger.LogContext;
import neptune.manager.utils.Logger.MessageType;

/**
 * @author Roberto Bifulco [RobertoBifulco.it] [info@robertoBifulco.it]
 * 
 */
public class InterfaceBuilder {

	private static String interfaceName = "eth";

	/**
	 * Costruisce una nuova interfaccia di rete per il nodo, generandone il mac
	 * address e il nome. L'interfaccia non e' aggiunta al nodo passato come
	 * argomento, che viene usato solo per determinare un nome univoco. Le
	 * eccezioni sollevate riguardano la generazione del MAC address, che
	 * avviene attraverso il {@link MACAddressBuilder}.
	 * 
	 * @param node
	 * @param macBuilder
	 * @param actual
	 *            la topologia di cui fa parte il node
	 * @return
	 * @throws ExperimentRepositoryException
	 * @throws StorageReadException
	 * @throws TopologyDefinitionException
	 */
	public static NetworkInterface buildNetInterface(Node node, LogContext log,
			Topology actual) throws ExperimentRepositoryException,
			StorageReadException, TopologyDefinitionException {

		DebugLog.printDetailedLog(
				"Interface building for node:" + node.getId(),
				InterfaceBuilder.class.getSimpleName());
		log.addMessage("Interface building for node:" + node.getId(),
				MessageType.NORMAL);

		NetworkInterface netIf = new NetworkInterface(
				defineNewInterfaceNameForNode(node), defineBindingMethod(),
				MACAddressBuilder.buildMACAddress(actual, log
						.createChild("MacBuilder")));

		return netIf;
	}

	private static String defineBindingMethod() {
		// TODO Auto-generated method stub
		return NetworkInterface.HIF;
	}

	/**
	 * Definisce un nome di interfaccia univoco all'interno del nodo passato
	 * come argomento
	 * 
	 * @param node
	 * @return
	 */
	public static String defineNewInterfaceNameForNode(Node node) {
		DebugLog.printDetailedLog("Interface name definition",
				InterfaceBuilder.class.getSimpleName());

		int i = 0;
		boolean found = false;
		while (!found) {
			DebugLog.printDetailedLog("Trying name:" + interfaceName + i,
					InterfaceBuilder.class.getSimpleName());
			if (node.getInterfaceByName(interfaceName + i) == null)
				found = true;
			else
				i++;
		}

		DebugLog.printDetailedLog(
				"Interface name defined:" + interfaceName + i,
				InterfaceBuilder.class.getSimpleName());

		return interfaceName + i;
	}
}
